package com.smashcrush.server.service.impl;

import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.servlet.http.Cookie;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.smashcrush.model.SecureObject;
import com.smashcrush.model.User;
import com.smashcrush.server.service.UserService;
import com.smashcrush.server.util.GUID;


/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
@Service("userServiceImpl")
@Transactional
public class UserServiceImpl implements UserService {

	private final static Log log = LogFactory.getLog(UserServiceImpl.class);

	@PersistenceContext
	EntityManager em;

	@Override
	public String register(String emailAddress, String password) {
		System.out.println("registering: " + emailAddress);

		User user = new User();
		user.setEmailAddress(emailAddress);
		user.setId(GUID.generate());
		user.setToken(GUID.generate());
		user.setPassword(password);
		user.setUpdatedDate(new Date());
		user.setCreatedDate(new Date());

		em.persist(user);

		return user.getId();
	}

	private void setCookie(String userId) {
		Cookie cookie = new Cookie("userId", userId);
		cookie.setMaxAge(60 * 60 * 24 * 365 * 10);
		// getThreadLocalResponse().addCookie(cookie);
	}

	private User findByEmailAddress(String emailAddress) {

		Query query = em.createQuery("SELECT o FROM " + User.class.getName()
				+ " o WHERE o.emailAddress=:emailAddress");
		query.setParameter("emailAddress", emailAddress);
		User user = null;

		List<User> users = query.getResultList();
		if (!users.isEmpty()) {
			user = users.get(0);
		}

		return user;
	}

	@Override
	public String login(String emailAddress, String password) throws Exception {

		boolean valid = false;

		User user = findByEmailAddress(emailAddress);

		if (user == null || !user.getPassword().equals(password)) {
			user = null;
		}

		log.debug("user: " + user);

		return user == null ? null : user.getToken();
	}

	@Override
	public Boolean isLoggedIn() {
		return false;
		// String userId = (String) getThreadLocalRequest().getSession()
		// .getAttribute(SESSION_ATTR_USER_ID);
		//
		// return userId != null;
	}

	@Override
	public void logout() {
		// TODO Auto-generated method stub

	}

	@Override
	public User findByToken(String token) {

		Query query = em.createQuery("SELECT o FROM "
				+ User.class.getCanonicalName() + " o WHERE o.token=:token");

		query.setParameter("token", token);

		return (User) query.getSingleResult();
	}

	@Override
	public void authorize(String token, SecureObject object) {
		User user = findByToken(token);

		if (object.getId() == null) {
			object.setId(UUID.randomUUID().toString());
			object.setUserId(user.getId());
		} else if (!user.getId().equals(object.getUserId())) {
			throw new RuntimeException("Invalid token");
		}

	}

}
